package com.future.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.future.mapper.DrivingUserStandardMapper;
import com.future.mapper.UserMapper;
import com.future.mapper.UserRoleMapper;
import com.future.po.DrivingUserStandard;
import com.future.po.User;
import com.future.po.UserRole;
import com.future.service.AuthService;
import com.future.service.UserService;
import com.future.utils.BeanUtils;
import com.future.utils.FileUtil;
import com.future.vo.PasswordVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.PasswordService;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.UUID;

@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class AuthServiceImpl implements AuthService {

    @Autowired
    private PasswordService passwordService;

    @Autowired
    private UserService userService;

    @Autowired
    @SuppressWarnings("all")
    private UserRoleMapper userRoleMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private DrivingUserStandardMapper drivingUserStandardMapper;

    @Override
    public void regist(@RequestBody User user) {
        // user设置默认照片
        user.setHeadPath("C:\\images\\user\\head\\default\\default.jpg");
        // 随机id
        Integer tmp = UUID.randomUUID().toString().hashCode();
        user.setId(tmp < 0 ? -tmp : tmp);
        // 加密
        PasswordVo passwordVo = new PasswordVo();
        passwordVo.setPassword(user.getPassword());
        passwordVo.setSalt(user.getUsername());
        String encryptPassword = passwordService.encryptPassword(passwordVo);

        user.setPassword(encryptPassword);
        // 更新user内容没必要
        userService.update(user, new UpdateWrapper<User>().eq("id", user.getId()));

        UserRole userRole = new UserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(2);

        if (userRoleMapper.insert(userRole) > 0){
            if(userMapper.insert(user) > 0){
                if (drivingUserStandardMapper.insert(new DrivingUserStandard(null, LocalDateTime.now(), LocalDateTime.now(), user.getId(), null)) > 0){
                    System.out.println("regist success!");
                }
            }
        }
    }

    @Override
    public User login(String username, String password) throws IOException {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);

        token.setRememberMe(true);
        subject.login(token);
        User user = (User) subject.getPrincipal();


        Session shiroSession = subject.getSession();
        shiroSession.setAttribute("user", user);

        try {
            byte[] bytes = FileUtil.readFileByBytes(user.getHeadPath());
            user.setHead(bytes);
        }catch (Exception e){
            return user;
        }

        return user;
    }

    @Override
    public void logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
    }

    @Override
    public boolean modifyPassword(PasswordVo passwordVo) {
        User user = userService.getById(passwordVo.getUserId());

        passwordVo.setSalt(user.getUsername());
        String encryptPassword = passwordService.encryptPassword(passwordVo);

        if (encryptPassword.equals(user.getPassword())) {
            passwordVo.setPassword(passwordVo.getNewPassword());
            user.setPassword(passwordService.encryptPassword(passwordVo));
            userService.update(user, new UpdateWrapper<User>().eq("id", user.getId()));
            return true;
        }

        return false;
    }
}
